package gc.analyze;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;

import org.junit.After;
import org.junit.Assert;
import org.junit.Test;

public class Extract_utest {
	File file_;

	@After
	public void tearDown() {
		File file = file_;
		file_ = null;
		if (file != null) if (!file.delete()) file.deleteOnExit();
	}

	@Test
	public void testTypical() throws Exception {
		file_ = file(
			running("10.1234567"),
			stopped( "0.7654321"),
			running("11.6666666")
		);
		long[] actual = Extract.parse(file_);
		Assert.assertArrayEquals(new long[] {
			10_1234567,
			   7654321,
			11_6666666,
		}, actual);
	}

	@Test
	public void testWrongOrder() throws Exception {
		file_ = file(
				stopped( "1.7654321"),
				running("10.1234567"),
				running("11.1234567"),
				stopped( "2.7654321")
			);
			long[] actual = Extract.parse(file_);
			Assert.assertArrayEquals(new long[] {
				         0,
				 1_7654321,
				10_1234567,
				         0,
				11_1234567,
				 2_7654321,
				         0,
			}, actual);
	}

	@Test
	public void testWithGarbage() throws Exception {
		file_ = file(
			"ABC",
			running("10.1234567"),
			"DEF",
			stopped( "0.7654321"),
			"GHJ",
			running("11.6666666"),
			"IJK"
		);
		long[] actual = Extract.parse(file_);
		Assert.assertArrayEquals(new long[] {
			10_1234567,
			   7654321,
			11_6666666,
		}, actual);
	}

	@Test
	public void testSubsequence1() {
		long[] input = { 10, 20, 30, 40, 50, };
		long[] expected = { 6, 20, 30, 40, 14, };
		long[] actual = Extract.subsequence(input, 4, 114);
		Assert.assertArrayEquals(expected, actual);
	}

	@Test
	public void testSubsequence2() {
		long[] input = { 10, 20, 30, 40, 50, };
		long[] expected = { 0, 19, 30, 40, 14, };
		long[] actual = Extract.subsequence(input, 11, 114);
		Assert.assertArrayEquals(expected, actual);
	}

	@Test
	public void testSubsequence3() {
		long[] input = { 10, 20, 30, 40, 50, };
		long[] expected = { 4, 20, 30, 39, 0, };
		long[] actual = Extract.subsequence(input, 6, 99);
		Assert.assertArrayEquals(expected, actual);
	}

	@Test
	public void testSubsequenceSingle1() {
		long[] input = { 10, 20, 30, 40, 50, };
		long[] expected = { 10, };
		long[] actual = Extract.subsequence(input, 35, 45);
		Assert.assertArrayEquals(expected, actual);
	}

	@Test
	public void testSubsequenceSingle2() {
		long[] input = { 10, 20, 30, 40, 50, };
		long[] expected = { 0, 10, 0, };
		long[] actual = Extract.subsequence(input, 65, 75);
		Assert.assertArrayEquals(expected, actual);
	}

	@Test
	public void testSubsequenceExact1() {
		long[] input = { 10, 20, 30, 40, 50, };
		long[] expected = { 30, };
		long[] actual = Extract.subsequence(input, 30, 60);
		Assert.assertArrayEquals(expected, actual);
	}

	@Test
	public void testSubsequenceExact2() {
		long[] input = { 10, 20, 30, 40, 50, };
		long[] expected = { 0, 40, 0, };
		long[] actual = Extract.subsequence(input, 60, 100);
		Assert.assertArrayEquals(expected, actual);
	}

	@Test
	public void testSubsequenceEndOut() {
		long[] input = { 10, 20, 30, 40, 50, };
		long[] expected = { 0, 40, 60, };
		long[] actual = Extract.subsequence(input, 60, 160);
		Assert.assertArrayEquals(expected, actual);
	}

	@Test
	public void testSubsequenceStartOut() {
		long[] input = { 10, 20, 30, 40, 50, };
		long[] expected = { 51, };
		long[] actual = Extract.subsequence(input, 149, 200);
		Assert.assertArrayEquals(expected, actual);
	}

	@Test
	public void testSubsequenceNegativeStart() {
		long[] input = { 10, 20, 30, 40, 50, };
		long[] expected = { 20, 20, 30, 40, 100, };
		long[] actual = Extract.subsequence(input, -10, 200);
		Assert.assertArrayEquals(expected, actual);
	}

	static String running(String number) {
		return "Application time: " + number + " seconds";
	}

	static String stopped(String number) {
		return "Total time for which application threads were stopped: " + number + " seconds";
	}

	static File file(String... lines) throws IOException {
		File file = File.createTempFile("Extract_utest", ".tmp");
		PrintStream ps = new PrintStream(file);
		try {
			for (String line : lines) {
				ps.println(line);
			}
		} finally {
			ps.close();
		}
		return file;
	}
}
